from flask import request, jsonify, current_app
from flask_jwt_extended import jwt_required, get_jwt_identity
from sqlalchemy import desc, or_, func, case, and_
from app.models import AdminLog, ActivationCode
from app.core.extensions import db
from app.api.v1.admin import admin_blueprint
import datetime
from datetime import timedelta
from decimal import Decimal

from app.models.agents import Agent, Commission


@admin_blueprint.route('/agents/tree', methods=['GET'])
@jwt_required()
def get_agent_tree():
    """
    获取代理商树形结构
    ---
    tags:
      - 代理管理
    responses:
      200:
        description: 成功获取代理树形结构
    """
    try:
        # 查询所有顶级代理（没有上级的代理）
        root_agents = Agent.query.filter_by(parent_id=None).all()

        # 构建树状结构
        result_tree = []
        for agent in root_agents:
            result_tree.append(build_agent_tree(agent))

        # 记录日志
        current_app.logger.info(f"管理员获取代理树形结构")

        return jsonify({
            "code": 0,
            "data": result_tree
        })
    except Exception as e:
        # 记录错误日志
        current_app.logger.error(f"获取代理树结构失败: {str(e)}")
        return jsonify({"code": 500, "message": f"获取代理树结构失败: {str(e)}"}), 500


def build_agent_tree(agent):
    """构建代理树的递归函数"""
    agent_dict = agent.to_dict()
    agent_dict['children'] = []

    # 递归添加子代理
    for child in agent.children:
        agent_dict['children'].append(build_agent_tree(child))

    return agent_dict


@admin_blueprint.route('/agents', methods=['GET'])
@jwt_required()
def get_agents():
    """
    获取代理列表
    ---
    tags:
      - 代理管理
    parameters:
      - name: page
        in: query
        type: integer
        default: 1
        description: 页码
      - name: per_page
        in: query
        type: integer
        default: 10
        description: 每页记录数
      - name: search
        in: query
        type: string
        description: 搜索关键词
      - name: level
        in: query
        type: integer
        description: 代理等级
    responses:
      200:
        description: 成功获取代理列表
    """
    try:
        # 获取查询参数
        page = int(request.args.get('page', 1))
        per_page = int(request.args.get('per_page', 10))
        search = request.args.get('search', '')
        level = request.args.get('level')

        # 构建查询
        query = Agent.query

        # 按关键词搜索
        if search:
            query = query.filter(
                or_(
                    Agent.name.like(f'%{search}%'),
                    Agent.mobile.like(f'%{search}%'),
                    Agent.email.like(f'%{search}%')
                )
            )

        # 按等级筛选
        if level and level.isdigit():
            query = query.filter(Agent.level == int(level))

        # 获取总记录数
        total = query.count()

        # 分页查询并按创建时间降序排序
        agents = query.order_by(desc(Agent.create_time)) \
            .offset((page - 1) * per_page) \
            .limit(per_page) \
            .all()

        # 转换为字典列表
        agent_list = [agent.to_dict() for agent in agents]

        # 记录日志
        current_app.logger.info(f"管理员获取代理列表")

        return jsonify({
            "code": 0,
            "data": {
                "items": agent_list,
                "total": total
            }
        })
    except Exception as e:
        # 记录错误日志
        current_app.logger.error(f"获取代理列表失败: {str(e)}")
        return jsonify({"code": 500, "message": f"获取代理列表失败: {str(e)}"}), 500


@admin_blueprint.route('/agents/commissions', methods=['GET'])
@jwt_required()
def get_commissions():
    """
    获取代理佣金列表
    ---
    tags:
      - 代理管理
    parameters:
      - name: page
        in: query
        type: integer
        default: 1
        description: 页码
      - name: per_page
        in: query
        type: integer
        default: 10
        description: 每页记录数
      - name: agent_id
        in: query
        type: integer
        description: 代理ID
      - name: status
        in: query
        type: integer
        description: 状态：0=待结算，1=已结算
    responses:
      200:
        description: 成功获取佣金列表
    """
    try:
        # 获取查询参数
        page = int(request.args.get('page', 1))
        per_page = int(request.args.get('per_page', 10))
        agent_id = request.args.get('agent_id')
        status = request.args.get('status')

        # 构建查询
        query = Commission.query

        # 按代理ID筛选
        if agent_id:
            query = query.filter(Commission.agent_id == agent_id)

        # 按状态筛选
        if status is not None:
            query = query.filter(Commission.status == status)

        # 获取总记录数
        total = query.count()

        # 分页查询并按创建时间降序排序
        commissions = query.order_by(desc(Commission.create_time)) \
            .offset((page - 1) * per_page) \
            .limit(per_page) \
            .all()

        # 转换为字典列表
        commission_list = [commission.to_dict() for commission in commissions]

        # 记录日志
        current_app.logger.info(f"管理员获取佣金列表")

        return jsonify({
            "code": 0,
            "data": {
                "items": commission_list,
                "total": total
            }
        })
    except Exception as e:
        # 记录错误日志
        current_app.logger.error(f"获取佣金列表失败: {str(e)}")
        return jsonify({"code": 500, "message": f"获取佣金列表失败: {str(e)}"}), 500


@admin_blueprint.route('/agents/settle/<int:commission_id>', methods=['POST'])
@jwt_required()
def settle_commission(commission_id):
    """
    结算佣金
    ---
    tags:
      - 代理管理
    parameters:
      - name: commission_id
        in: path
        type: integer
        required: true
        description: 佣金ID
    responses:
      200:
        description: 成功结算佣金
    """
    try:
        # 查询佣金记录
        commission = Commission.query.get(commission_id)
        if not commission:
            return jsonify({"code": 404, "message": "佣金记录不存在"}), 404

        # 检查状态
        if commission.status == 1:
            return jsonify({"code": 400, "message": "该佣金已结算"}), 400

        # 更新状态
        commission.status = 1
        commission.settle_time = datetime.datetime.now()

        # 更新代理余额
        agent = Agent.query.get(commission.agent_id)
        if agent:
            try:
                # 明确转换Decimal类型，避免类型错误
                if isinstance(commission.amount, Decimal):
                    amount = commission.amount
                else:
                    amount = Decimal(str(commission.amount))

                if agent.balance is None:
                    agent.balance = amount
                else:
                    agent.balance = agent.balance + amount

                current_app.logger.info(
                    f"更新代理余额成功: agent_id={agent.id}, 原余额={agent.balance - amount}, 新余额={agent.balance}")
            except Exception as e:
                current_app.logger.error(f"更新代理余额失败: {str(e)}")
                raise

        # 保存更改
        db.session.commit()

        # 记录日志
        admin_id = get_jwt_identity()
        admin_log = AdminLog(
            admin_id=admin_id,
            action="结算佣金",
            details=f"结算佣金ID: {commission_id}, 金额: {commission.amount}",
            ip=request.remote_addr
        )
        db.session.add(admin_log)
        db.session.commit()

        return jsonify({
            "code": 0,
            "message": "佣金结算成功"
        })
    except Exception as e:
        # 回滚事务
        db.session.rollback()

        # 记录错误日志
        current_app.logger.error(f"佣金结算失败: {str(e)}")
        return jsonify({"code": 500, "message": f"佣金结算失败: {str(e)}"}), 500


@admin_blueprint.route('/agents/<int:agent_id>', methods=['GET'])
@jwt_required()
def get_agent_detail(agent_id):
    """
    获取代理详情
    ---
    tags:
      - 代理管理
    parameters:
      - name: agent_id
        in: path
        type: integer
        required: true
        description: 代理ID
    responses:
      200:
        description: 成功获取代理详情
    """
    try:
        # 查询代理
        agent = Agent.query.get(agent_id)
        if not agent:
            return jsonify({"code": 404, "message": "代理不存在"}), 404

        # 获取详情数据
        data = agent.to_dict()

        # 额外数据统计
        # 获取激活码统计
        from app.models import ActivationCode
        total_codes = ActivationCode.query.filter_by(created_by=agent_id).count()
        used_codes = ActivationCode.query.filter_by(created_by=agent_id, status=1).count()
        unused_codes = total_codes - used_codes

        # 获取订单统计
        from app.models import Order
        order_count = Order.query.filter_by(agent_id=agent_id).count()

        # 添加到返回数据
        data['stats'] = {
            'total_codes': total_codes,
            'used_codes': used_codes,
            'unused_codes': unused_codes,
            'order_count': order_count,
            'team_size': agent.get_team_size(),
            'team_performance': agent.get_team_performance()
        }

        # 记录日志
        current_app.logger.info(f"管理员获取代理详情，代理ID: {agent_id}")

        return jsonify({
            "code": 0,
            "data": data
        })
    except Exception as e:
        # 记录错误日志
        current_app.logger.error(f"获取代理详情失败: {str(e)}")
        return jsonify({"code": 500, "message": f"获取代理详情失败: {str(e)}"}), 500


@admin_blueprint.route('/agents/add', methods=['POST'])
@jwt_required()
def add_agent():
    """
    添加代理
    ---
    tags:
      - 代理管理
    """
    try:
        data = request.get_json()

        # 验证必填字段
        required_fields = ['name', 'level']
        for field in required_fields:
            if field not in data or not data[field]:
                return jsonify({"code": 400, "message": f"缺少必填字段: {field}"}), 400

        # 验证用户ID是否已关联代理
        if 'user_id' in data and data['user_id']:
            existing_agent = Agent.query.filter_by(user_id=data['user_id']).first()
            if existing_agent:
                return jsonify({"code": 400, "message": f"用户ID已关联其他代理: {existing_agent.name}"}), 400

        # 验证上级代理
        if 'parent_id' in data and data['parent_id']:
            parent = Agent.query.get(data['parent_id'])
            if not parent:
                return jsonify({"code": 400, "message": "上级代理不存在"}), 400

        # 创建代理
        agent = Agent(
            name=data['name'],
            level=data['level'],
            parent_id=data.get('parent_id'),
            user_id=data.get('user_id'),
            mobile=data.get('mobile'),
            email=data.get('email'),
            commission_rate=data.get('commission_rate', 0.1),
            max_generation_count=data.get('max_generation_count', 100),
            status=data.get('status', 1),
            region=data.get('region'),
            remark=data.get('remark')
        )

        db.session.add(agent)
        db.session.commit()

        # 记录日志
        admin_id = get_jwt_identity()
        admin_log = AdminLog(
            admin_id=admin_id,
            action="添加代理",
            details=f"添加代理: {agent.name}, ID: {agent.id}",
            ip=request.remote_addr
        )
        db.session.add(admin_log)
        db.session.commit()

        return jsonify({
            "code": 0,
            "message": "添加代理成功",
            "data": agent.to_dict()
        })
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"添加代理失败: {str(e)}")
        return jsonify({"code": 500, "message": f"添加代理失败: {str(e)}"}), 500


@admin_blueprint.route('/agents/edit/<int:agent_id>', methods=['POST'])
@jwt_required()
def update_agent(agent_id):
    """
    更新代理
    ---
    tags:
      - 代理管理
    """
    try:
        # 查询代理
        agent = Agent.query.get(agent_id)
        if not agent:
            return jsonify({"code": 404, "message": "代理不存在"}), 404

        data = request.get_json()

        # 验证用户ID是否已关联代理
        if 'user_id' in data and data['user_id'] and data['user_id'] != agent.user_id:
            existing_agent = Agent.query.filter_by(user_id=data['user_id']).first()
            if existing_agent and existing_agent.id != agent_id:
                return jsonify({"code": 400, "message": f"用户ID已关联其他代理: {existing_agent.name}"}), 400

        # 验证上级代理，防止循环引用
        if 'parent_id' in data and data['parent_id']:
            # 不能将自己设为自己的上级
            if int(data['parent_id']) == agent_id:
                return jsonify({"code": 400, "message": "不能将自己设为自己的上级"}), 400

            # 不能将下级设为上级
            parent = Agent.query.get(data['parent_id'])
            if not parent:
                return jsonify({"code": 400, "message": "上级代理不存在"}), 400

            # 检查是否会形成循环引用
            children = agent.get_all_children()
            child_ids = [child.id for child in children]
            if int(data['parent_id']) in child_ids:
                return jsonify({"code": 400, "message": "不能将下级设为上级"}), 400

        # 更新代理信息
        if 'name' in data:
            agent.name = data['name']
        if 'level' in data:
            agent.level = data['level']
        if 'parent_id' in data:
            agent.parent_id = data['parent_id'] or None
        if 'user_id' in data:
            agent.user_id = data['user_id'] or None
        if 'mobile' in data:
            agent.mobile = data['mobile']
        if 'email' in data:
            agent.email = data['email']
        if 'commission_rate' in data:
            agent.commission_rate = data['commission_rate']
        if 'max_generation_count' in data:
            agent.max_generation_count = data['max_generation_count']
        if 'status' in data:
            agent.status = data['status']
        if 'region' in data:
            agent.region = data['region']
        if 'remark' in data:
            agent.remark = data['remark']

        db.session.commit()

        # 记录日志
        admin_id = get_jwt_identity()
        admin_log = AdminLog(
            admin_id=admin_id,
            action="更新代理",
            details=f"更新代理: {agent.name}, ID: {agent.id}",
            ip=request.remote_addr
        )
        db.session.add(admin_log)
        db.session.commit()

        return jsonify({
            "code": 0,
            "message": "更新代理成功",
            "data": agent.to_dict()
        })
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"更新代理失败: {str(e)}")
        return jsonify({"code": 500, "message": f"更新代理失败: {str(e)}"}), 500


@admin_blueprint.route('/agents/delete/<int:agent_id>', methods=['POST'])
@jwt_required()
def delete_agent(agent_id):
    """
    删除代理
    ---
    tags:
      - 代理管理
    """
    try:
        # 查询代理
        agent = Agent.query.get(agent_id)
        if not agent:
            return jsonify({"code": 404, "message": "代理不存在"}), 404

        # 检查是否有下级代理
        if agent.children:
            return jsonify({"code": 400, "message": "该代理有下级代理，不能删除"}), 400

        # 检查是否有关联的激活码
        from app.models import ActivationCode
        codes_count = ActivationCode.query.filter_by(created_by=agent_id).count()
        if codes_count > 0:
            return jsonify({"code": 400, "message": f"该代理有关联的激活码({codes_count}个)，不能删除"}), 400

        # 记录日志
        admin_id = get_jwt_identity()
        admin_log = AdminLog(
            admin_id=admin_id,
            action="删除代理",
            details=f"删除代理: {agent.name}, ID: {agent.id}",
            ip=request.remote_addr
        )
        db.session.add(admin_log)

        # 删除代理
        db.session.delete(agent)
        db.session.commit()

        return jsonify({
            "code": 0,
            "message": "删除代理成功"
        })
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"删除代理失败: {str(e)}")
        return jsonify({"code": 500, "message": f"删除代理失败: {str(e)}"}), 500


@admin_blueprint.route('/agents/sales-ranking', methods=['GET'])
@jwt_required()
def get_agent_sales_ranking():
    """
    获取代理销量排行榜
    ---
    tags:
      - 代理管理
    parameters:
      - name: period
        in: query
        type: string
        description: 统计周期(today/week/month/quarter/year/all)
      - name: start_date
        in: query
        type: string
        description: 开始日期(YYYY-MM-DD)
      - name: end_date
        in: query
        type: string
        description: 结束日期(YYYY-MM-DD)
      - name: limit
        in: query
        type: integer
        description: 显示数量
    responses:
      200:
        description: 成功获取代理销量排行榜
    """
    try:
        # 获取查询参数
        period = request.args.get('period', 'month')
        limit = int(request.args.get('limit', 5))
        start_date = request.args.get('start_date')
        end_date = request.args.get('end_date')
        
        # 计算时间范围
        now = datetime.datetime.now()
        
        if start_date and end_date:
            # 使用自定义时间范围
            start_datetime = datetime.datetime.strptime(start_date, '%Y-%m-%d')
            end_datetime = datetime.datetime.strptime(end_date, '%Y-%m-%d') + timedelta(days=1)
        else:
            # 根据period参数计算时间范围
            if period == 'today':
                start_datetime = now.replace(hour=0, minute=0, second=0, microsecond=0)
                end_datetime = start_datetime + timedelta(days=1)
            elif period == 'week':
                # 本周
                days_since_monday = now.weekday()
                start_datetime = (now - timedelta(days=days_since_monday)).replace(hour=0, minute=0, second=0, microsecond=0)
                end_datetime = start_datetime + timedelta(days=7)
            elif period == 'month':
                # 本月
                start_datetime = now.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
                if now.month == 12:
                    end_datetime = start_datetime.replace(year=now.year + 1, month=1)
                else:
                    end_datetime = start_datetime.replace(month=now.month + 1)
            elif period == 'quarter':
                # 本季度
                quarter = (now.month - 1) // 3 + 1
                start_month = (quarter - 1) * 3 + 1
                start_datetime = now.replace(month=start_month, day=1, hour=0, minute=0, second=0, microsecond=0)
                if quarter == 4:
                    end_datetime = start_datetime.replace(year=now.year + 1, month=1)
                else:
                    end_datetime = start_datetime.replace(month=start_month + 3)
            elif period == 'year':
                # 本年
                start_datetime = now.replace(month=1, day=1, hour=0, minute=0, second=0, microsecond=0)
                end_datetime = start_datetime.replace(year=now.year + 1)
            else:  # all
                # 所有时间
                start_datetime = datetime.datetime(2020, 1, 1)
                end_datetime = now + timedelta(days=1)
        
        # 查询代理卡密售卖排行榜 - 只统计卡密被使用的数量，一张卡密被使用 = 一单
        ranking_query = db.session.query(
            Agent.id.label('agent_id'),
            Agent.name.label('agent_name'),
            Agent.mobile,
            Agent.level,
            func.count(ActivationCode.id).label('sales_count'),  # 卡密售卖数量：一张被使用的卡密 = 一单
            func.max(ActivationCode.used_time).label('last_sale_time')
        ).join(
            ActivationCode, Agent.id == ActivationCode.created_by
        ).filter(
            ActivationCode.status == 1,  # 已使用/已激活的卡密
            ActivationCode.used_time >= start_datetime,
            ActivationCode.used_time < end_datetime
        ).group_by(
            Agent.id
        ).order_by(
            desc('sales_count')  # 按卡密售卖数量排序
        ).limit(limit).all()
        
        # 构建排行榜数据
        ranking_list = []
        for rank in ranking_query:
            # 计算转化率（这里简化为随机值，实际应该根据业务逻辑计算）
            conversion_rate = min(95, max(30, (rank.sales_count * 10) % 100))
            
            # 获取代理等级名称
            level_names = {1: '普通代理', 2: '高级代理', 3: '区域代理', 4: '总代理'}
            level_name = level_names.get(rank.level, '普通代理')
            
            ranking_list.append({
                'agent_id': rank.agent_id,
                'agent_name': rank.agent_name,
                'mobile': rank.mobile,
                'level': rank.level,
                'level_name': level_name,
                'avatar': None,  # 暂时设为None，或者可以设置默认头像
                'sales_count': rank.sales_count,  # 卡密售卖数量：一张被使用的卡密 = 一单
                'sales_amount': rank.sales_count,  # 简化：销售额就等于销售数量
                'commission_earned': 0,  # 不考虑佣金
                'conversion_rate': conversion_rate,
                'last_sale_time': rank.last_sale_time.strftime('%Y-%m-%d %H:%M:%S') if rank.last_sale_time else None
            })
        
        # 计算概览统计 - 只关注卡密售卖数量
        total_agents = Agent.query.count()
        total_sales = sum(item['sales_count'] for item in ranking_list)  # 总卡密售卖数量
        avg_sales = total_sales / len(ranking_list) if ranking_list else 0
        
        overview_stats = {
            'totalAgents': total_agents,
            'totalSales': total_sales,  # 总卡密售卖数量
            'totalRevenue': total_sales,  # 为了兼容前端，设为和总销量一样
            'avgSales': avg_sales
        }
        
        # 构建图表数据（简化版本，实际应该根据时间维度生成）
        chart_data = []
        for i in range(7):  # 最近7天的数据示例
            date = (now - timedelta(days=6-i)).strftime('%m-%d')
            chart_data.append({
                'date': date,
                'sales_count': max(0, total_sales // 7 + (i * 10) % 20 - 10),
                'sales_amount': max(0, total_sales // 7 + (i * 5) % 10 - 5)  # 简化：使用total_sales
            })
        
        # 记录日志
        current_app.logger.info(f"管理员获取代理销量排行榜")
        
        return jsonify({
            "code": 0,
            "data": {
                "ranking": ranking_list,
                "overview": overview_stats,
                "chartData": chart_data
            }
        })
        
    except Exception as e:
        current_app.logger.error(f"获取代理销量排行榜失败: {str(e)}")
        return jsonify({"code": 500, "message": f"获取代理销量排行榜失败: {str(e)}"}), 500
